﻿using IR.Common.Enums;
using IR.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IR.Model.Models
{
    public class MVersion
    {
        private string _versionID;
        private Status _status;
        private DateTime _dateCreated;

        #region ***Properties***
        public string VersionID
        {
            get { return _versionID; }
            set
            {
                if (value != null)
                    _versionID = value;
            }
        }

        public Status Status
        {
            get { return _status; }
            set
            {
                if (value != null)
                    _status = value;
            }
        }

        public DateTime DateCreated
        {
            get { return _dateCreated; }
            set
            {
                if (value != null)
                    _dateCreated = value;
            }
        }
        #endregion

        /// <summary>
        /// This will save the current version (new or old)
        /// </summary>
        /// <param name="allowOverwrite">Allow updating old versions</param>
        /// <returns>True if saved</returns>
        public bool Save(bool allowOverwrite = false)
        {
            IREntities context = new IREntities();

            // Set values as these are needed either way
            version currentversion = new version
            {
                idversion = _versionID,
                date_created = _dateCreated,
                status = (int) _status
            };

            // Check if new version
            version original = context.versions.Find(_versionID);

            if (original == null)
            {
                try
                {
                    context.versions.Add(currentversion);
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else if (allowOverwrite == true)
            {
                try
                {
                    context.Entry(original).CurrentValues.SetValues(currentversion);
                    context.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }

        /// <summary>
        /// Loads and returns a version (Can be used to initialize)
        /// </summary>
        /// <param name="usernameToLoad">VersionID to look for</param>
        /// <returns>Null if failed</returns>
        public static MVersion Load(string versionToLoad)
        {
            IREntities context = new IREntities();

            // Search for the version
            version original = context.versions.Find(versionToLoad);

            // If found load it
            if (original == null)
            {
                return null;
            }
            else
            {
                MVersion currentVersion = new MVersion();

                currentVersion._versionID = original.idversion;
                currentVersion._dateCreated = original.date_created;
                currentVersion._status = (Status)original.status;

                return currentVersion;
            }
        }

        /// <summary>
        /// Gets all versions currently in the DB
        /// </summary>
        /// <returns>List of all versions</returns>
        private static List<MVersion> GetAllVersions()
        {
            IREntities context = new IREntities();

            List<version> rowList = context.versions.Select(v => v).ToList();
            List<MVersion> returnList = new List<MVersion>(10);

            foreach (version row in rowList)
            {
                MVersion currentVersion = new MVersion();

                currentVersion.VersionID = row.idversion;
                currentVersion.DateCreated = row.date_created;
                currentVersion.Status = (Status)row.status;

                returnList.Add(currentVersion);
            }

            return returnList;
        }

        /// <summary>
        /// Runs a query on the version table based on a Dictionary you pass in
        /// </summary>
        /// <param name="queries">Dictonary... key = column name, value = value in column</param>
        /// <returns>List of MVersions matching all params, all if null param</returns>
        public static List<MVersion> QueryVersions(Dictionary<string, object> queries)
        {
            IREntities context = new IREntities();

            var listOfProperties = typeof(MVersion).GetProperties().ToList();

            List<MVersion> returnVersions = GetAllVersions();

            foreach (KeyValuePair<string, object> currentQuery in queries)
            {
                // Gets the current property (column) by stripping off the opening part that defines the namespace
                var currentProperty = listOfProperties
                    .Where(p => p.ToString().Split(' ').ElementAtOrDefault(1) == currentQuery.Key).FirstOrDefault();
                // Filters 'in' all rows that have the column value asked for
                //(so if multiple values are asked for it only returns rows with all values asked for)
                returnVersions = returnVersions.Where(v => currentProperty.GetValue(v).ToString() == currentQuery.Value.ToString()).ToList();
            }

            return returnVersions;
        }
    }
}
